import json
import re

from django.contrib.auth import login
from django.db import DatabaseError
from django.http import JsonResponse, HttpResponseBadRequest, HttpResponse
from django.shortcuts import render
# Create your views here.
from django.views import View
from QQLoginTool.QQtool import OAuthQQ
from django.conf import settings
from apps.users.models import User
from apps.oauth.models import OAuthQQUser
from django_redis import get_redis_connection


class QQOauthURLView(View):
    """
    https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=xxx&redirect_uri=xxx&state=xxx
    """
    def get(self, request):
        # 111、初始化OAuthQQ对象
        qq_oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                           client_secret=settings.QQ_CLIENT_SECRET,
                           redirect_uri=settings.QQ_REDIRECT_URI,
                           state="test")

        # 222、获取QQ登录扫码页面，扫码后得到Authorization Code
        login_url = qq_oauth.get_qq_url()
        return JsonResponse({'code': 0, 'errmsg': 'ok', 'login_url': login_url})


class QQAuthUserView(View):
    def get(self, request):
        # GET this.host + '/oauth_callback/?code=' + code
        code = request.GET.get('code')
        if not code:
            return HttpResponseBadRequest('缺少code')
        qq_oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                           client_secret=settings.QQ_CLIENT_SECRET,
                           redirect_uri=settings.QQ_REDIRECT_URI,
                           state="test")
        # 333、通过Authorization Code获取Access Token
        # '1137C1B8F28BF717BB7E5AACF61E75B2'
        access_token_qq = qq_oauth.get_access_token(code)
        # 444、通过Access Token获取 OpenID
        # 'FF573DFCC754B980ECFE24B859E60E32'
        open_id = qq_oauth.get_open_id(access_token_qq)
        # ------加密Openid---------
        from utils.utils import generate_access_token
        access_token = generate_access_token(open_id)
        # ------------------------
        # # 判断是否已绑定美多账号
        try:
            qq_user = OAuthQQUser.objects.get(openid__exact=open_id)
        except OAuthQQUser.DoesNotExist as e:
            #  未绑定，跳转绑定页面
            return JsonResponse({'code': 400, 'errmsg': '用户未绑定', 'access_token': access_token})
        else:
            # # 状态保持，设置cookie
            login(request, qq_user.user)
            response = JsonResponse({'code': 0, 'errmsg': 'ok'})
            response.set_cookie('username', qq_user.user.username)
            return response

    def post(self, request):
        # 1、获取前端数据  POST  this.host + '/oauth_callback/'
        data_dict = json.loads(request.body.decode())
        mobile = data_dict.get('mobile')
        password = data_dict.get('password')
        sms_code = data_dict.get('sms_code')
        access_token = data_dict.get('access_token')
        # 2、检验数据
        if not all([mobile, password, sms_code, access_token]):
            return JsonResponse({'code': 400, 'errmsg': '参数不全'})
        if not re.match(r'^[a-zA-Z0-9_-]{8,20}$', password):
            return JsonResponse({'code': 400, 'errmsg': '密码格式不符合要求，请重新输入'})
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({'code': 400, 'errmsg': '手机号格式不符合要求，请重新输入'})
        redis_cli = get_redis_connection('verifications_code')
        redis_sms_code = redis_cli.get(mobile)
        if not redis_sms_code:
            return JsonResponse({'code': 400, 'errmsg': '短信验证码已失效'})
        if sms_code != redis_sms_code.decode():
            return JsonResponse({'code': 400, 'errmsg': '短信验证码输入有误'})
        # --------解密Openid-----------
        from utils.utils import check_access_token
        open_id = check_access_token(access_token)
        if not open_id:
            return JsonResponse({'code': 400, 'errmsg': '缺少openid'})
        # ----------------------------
        # 3、判断手机号是否已注册
        try:
            user = User.objects.get(mobile__exact=mobile)
        except User.DoesNotExist as e:
            # 3.1、未注册，保存数据库数据
            user = User.objects.create_user(username=mobile, password=password, mobile=mobile)
        else:
            # 3.2、已注册，判断密码是否正确，保存数据库数据
            if not user.check_password(password):
                return JsonResponse({'code': 400, 'errmsg': '密码输入有误'})
        try:
            OAuthQQUser.objects.create(user=user, openid=open_id)
        except DatabaseError as e:
            # print(e)
            return JsonResponse({'code': 400, 'errmsg': '往数据库添加数据出错'})
        # 4、状态保持，设置cookie
        login(request, user)
        response = JsonResponse({'code': 0, 'errmsg': 'ok'})
        response.set_cookie('username', user.username)
        # 5、返回Json数据
        return response

